<template>
  <div class="table-module px-3">
    <!-- 查询 -->
    <!--  
          实现：通过我们配置好的 查询条件
              首先去创建form表单，根据我们配置的查询条件去做一个循环判断，展示出不用类型所对应不同的输入框
              比如：text对应普通的输入框，select对应下拉选择，dateTime对应日期时间选择器
              在使用时，父组件会传来一个queryForm空的对象，
              循环出来的输入框会绑定表格配置中的prop字段绑定在queryForm对象中
       -->
    <div class="py-3" ref="queryRef">
      <el-row>
        <el-col :span="24">
          <el-form
            v-if="props.tableModule.query"
            :inline="true"
            :model="props.tableModule.queryForm"
            label-position="left"
            label-width="5em"
          >
            <!-- slot插槽（用来添加表格查询条件） -->
            <slot name="select"></slot>
            <el-form-item
              :label="item.label"
              v-for="item in props.tableModule.query"
              :key="item.prop"
            >
              <el-input
                v-model="props.tableModule.queryForm[item.prop]"
                :placeholder="'输入' + item.label + '关键字'"
                :clearable="item.clearable"
                v-if="item.type == 'text'"
                class="w-52"
                @change="selectChange(item.prop)"
              ></el-input>
              <el-select
                v-model="props.tableModule.queryForm[item.prop]"
                :clearable="item.clearable"
                :placeholder="'选择' + item.label + '关键字'"
                v-else-if="item.type == 'select'"
                class="w-52"
                @change="selectChange(item.prop)"
              >
                <el-option
                  v-for="cItem in item.options"
                  :key="item.valueKey ? cItem[item.valueKey] : cItem"
                  :label="item.labelKey ? cItem[item.labelKey] : cItem"
                  :value="item.valueKey ? cItem[item.valueKey] : cItem"
                />
              </el-select>
              <el-select
                v-model="props.tableModule.queryForm[item.prop]"
                :clearable="item.clearable"
                allow-create
                default-first-option
                :placeholder="'选择' + item.label + '关键字'"
                v-else-if="item.type == 'createSelect'"
                class="w-52"
                @change="selectChange(item.prop)"
              >
                <el-option
                  v-for="cItem in item.options"
                  :key="item.valueKey ? cItem[item.valueKey] : cItem"
                  :label="item.labelKey ? cItem[item.labelKey] : cItem"
                  :value="item.valueKey ? cItem[item.valueKey] : cItem"
                />
              </el-select>
              <el-date-picker
                v-model="props.tableModule.queryForm[item.prop]"
                :clearable="item.clearable"
                type="datetimerange"
                format="YYYY/MM/DD"
                value-format="YYYY-MM-DD"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                v-else-if="item.type == 'date'"
                @change="selectChange(item.prop)"
              />
              <el-date-picker
                v-model="props.tableModule.queryForm[item.prop]"
                format="YYYY"
                value-format="YYYY"
                type="year"
                :placeholder="'选择' + item.label"
                v-else-if="item.type == 'year'"
                style="width: 100%"
                @change="selectChange(item.prop)"
              />
            </el-form-item>
          </el-form>
        </el-col>
        <el-col :span="24">
          <el-button-group>
            <el-button
              v-if="props.tableModule.query"
              @click="Search"
              type="primary"
              plain
              >查询</el-button
            >
            <el-button @click="Recover">重置</el-button>
            <!-- slot插槽（用来添加表格其他操作，比如，新增数据，删除数据等其他操作） -->
            <slot name="event"></slot>
            <!-- 
                  动态表头显示，根据表格每条配置项中的show字段来决定改列是否显示或者隐藏 
                  columns 就是我们表格配置的数组对象
              -->
            <el-popover
              placement="bottom"
              title="表格配置"
              :width="200"
              trigger="click"
            >
              <div
                v-for="(item, index) in props.tableModule.columns"
                :key="index"
              >
                <el-checkbox
                  v-model="item.show"
                  :label="item.label"
                  :true-label="1"
                  :false-label="0"
                />
              </div>
              <template #reference>
                <!-- 一个Element Plus中的图标 -->
                <el-button :icon="SetUp"></el-button>
              </template>
            </el-popover>
          </el-button-group>
        </el-col>
      </el-row>
      <!-- <div class="flex justify-end">
          </div> -->
      <!-- <div class="flex items-start">
      </div> -->
    </div>
    <!-- 表格 -->
    <!-- style中是计算表格的高度的 -->
    <el-table
      :data="props.tableModule.dataList"
      border
      :style="{
        height: `calc(100vh - ${height}px)`,
      }"
      v-loading="props.tableModule.loading"
      :row-class-name="tableRowClassName"
      :cell-class-name="tableCellClassName"
      @selection-change="handleSelectionChange"
      id="el-table"
      ref="tableRef"
    >
      <!-- @cell-dblclick="cellDblClick" -->
      <el-table-column
        v-if="props.tableModule.multipleSelection"
        fixed
        type="selection"
        width="50"
        align="center"
      />
      <!-- columns表格配置数据 -->
      <template v-for="(item, index) in props.tableModule.columns">
        <!-- 循环 columns 紧接着判断每个字段的类型 -->
        <el-table-column
          :prop="item.prop"
          :label="item.label"
          :align="item.align || 'left'"
          :width="item.width"
          :min-width="item.min_width"
          :fixed="item.fixed"
          v-if="item.show"
        >
          <template slot-scope="scope" #default="scope">
            <!-- switch时使用switch开关组件，并且绑定好我们配置的属性 -->
            <div v-if="item.type == 'switch'">
              <el-switch
                v-model="scope.row[item.prop]"
                :active-value="item.activeValue"
                :inactive-value="item.inactiveValue"
                @change="props.tableModule.switchChange(scope.row)"
              >
              </el-switch>
            </div>
            <!-- status 时 使用fieldChange方法匹配出值对应的名称并返回 -->
            <div v-else-if="item.type == 'status'">
              <el-tag :type="fieldChange(scope.row[item.prop], item.color)">{{
                fieldChange(scope.row[item.prop], item.option)
              }}</el-tag>
            </div>
            <!-- image 就是使用 el-image展示我们的图片咯 -->
            <div v-else-if="item.type == 'image'">
              <el-image
                style="width: 60px; height: 60px"
                :src="scope.row[item.prop]"
                :preview-src-list="[scope.row[item.prop]]"
                :preview-teleported="true"
              >
                <template #error>
                  <div class="image-slot">
                    <el-icon size="60"><icon-picture /></el-icon>
                  </div>
                </template>
              </el-image>
            </div>
            <!-- formatDate 方法将时间戳格式化为年月日时分秒的格式 -->
            <div v-else-if="item.type == 'time'">
              {{ formatDate(scope.row[item.prop]) }}
            </div>
            <!-- formatYear 方法将时间戳格式化为年份 -->
            <div v-else-if="item.type == 'year'">
              {{ formatYear(scope.row[item.prop]) }}
            </div>
            <div v-else-if="item.type == 'selectView'">
              {{ findOption(scope.row[item.prop], item.options) }}
            </div>
            <!-- 可编辑单元格 -->
            <div v-else-if="item.isEdit">
              <div v-if="item.type == 'select'">
                <el-select
                  v-model="scope.row[item.prop]"
                  :placeholder="'请输入' + item.label"
                  @blur="inputBlur(scope.row)"
                  autofocus
                  ref="selectRef"
                  v-if="
                    scope.row['Indexs'] == props.tableModule.rowIndex &&
                    scope.column['Indexs'] == props.tableModule.columnIndex
                  "
                >
                  <el-option
                    v-for="cItem in item.options"
                    :key="item.valueKey ? cItem[item.valueKey] : cItem"
                    :label="item.labelKey ? cItem[item.labelKey] : cItem"
                    :value="item.valueKey ? cItem[item.valueKey] : cItem"
                  />
                </el-select>
                <div v-else>
                  {{ findOption(scope.row[item.prop], item.options) }}
                </div>
              </div>
              <div v-else>
                <el-input
                  v-model="scope.row[item.prop]"
                  :placeholder="'请输入' + item.label"
                  @blur="inputBlur(scope.row)"
                  autofocus
                  ref="inputRef"
                  v-if="
                    scope.row['Indexs'] == props.tableModule.rowIndex &&
                    scope.column['Indexs'] == props.tableModule.columnIndex
                  "
                />
                <div v-else>{{ scope.row[item.prop] }}</div>
              </div>
            </div>
            <!-- 类型都不匹配时直接展示 -->
            <div v-else>{{ scope.row[item.prop] }}</div>
          </template>
        </el-table-column>
      </template>
      <!-- 这里的插槽用于列表的操作列 -->
      <slot name="tableColumn"></slot>
    </el-table>
    <!-- 分页 -->
    <!-- 分页这里没什么可说的，父组件传三个参数，当前页，每页条数，总条数就可以了。 -->
    <div ref="paginationRef" class="flex justify-center">
      <el-pagination
        v-if="props.tableModule.pages"
        class="py-3"
        :current-page="props.tableModule.pages.page"
        :page-size.sync="props.tableModule.pages.limit"
        :page-sizes="pageSizes"
        :layout="layout"
        background
        :total="props.tableModule.pages.total"
        @size-change="sizeChange"
        @current-change="currentChange"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script setup>
import {
  Picture as IconPicture,
  Operation,
  Plus,
  SetUp,
} from "@element-plus/icons-vue";
import { onMounted, reactive, toRefs, ref } from "vue";
import { formatDate, formatYear } from "@/utils"; // 自己的格式化时间的方法

const props = defineProps({
  tableModule: Object, // 由父组件传递而来
  layout: {
    // 分页功能配置
    type: String,
    default: "total, sizes, prev, pager, next, jumper",
  },
  pageSizes: {
    // 分页：每页条数配置
    type: Array,
    default() {
      return [10, 20, 30, 50];
    },
  },
});

const state = reactive({
  // rowIndex: 0, // 行索引 用于可编辑单元格
  // columnIndex: 0, // 列索引 用于可编辑单元格
  height: 0,
});

const {
  // rowIndex,
  // columnIndex,
  height,
} = toRefs(state);

const queryRef = ref();
const paginationRef = ref();

onMounted(() => {
  // 这里拿到query模块的高度，适配页面高度的
  setTimeout(() => {
    const heightRef =
      queryRef.value.clientHeight +
      paginationRef.value.clientHeight +
      props.tableModule.height +
      6;
    // console.log(`output->heightRef`, heightRef);
    state.height = heightRef;
  }, 200);
  // 为每个表格配置项添加show属性，默认1为显示状态
  props.tableModule.columns.forEach((item) => {
    item.show = 1;
  });
});

function fieldChange(row, option) {
  if (option[row]) {
    return option[row];
  }
}

function findOption(val, arr) {
  // console.log(`output->findOption`, val, arr);
  const foundOption = arr.find((option) => {
    return option.value === val;
  });
  // console.log(`output->`, foundOption);
  return foundOption.label;
}

// 编辑单元格 ----------
// 为每一行返回固定的className
function tableRowClassName({ row, rowIndex }) {
  row.Indexs = rowIndex;
}

// 为所有单元格设置一个固定的 className
function tableCellClassName({ column, columnIndex }) {
  column.Indexs = columnIndex;
}

// el-table单元格双击事件
function cellDblClick(row, column, cell, event) {
  // console.log(`output->`, row, column, cell, event);
  props.tableModule.rowIndex = row.Indexs;
  props.tableModule.columnIndex = column.Indexs;
}

// input失去焦点
function inputBlur(row) {
  // props.tableModule.rowIndex = null;
  // props.tableModule.columnIndex = null;
  props.tableModule.editInputBlur(); // 父组件的方法，
}

// 每页条数切换时触发
function sizeChange(item) {
  props.tableModule.pages.limit = item;
  props.tableModule.callback(); // 父组件绑定的回调
}

// 页数切换时触发
function currentChange(item) {
  props.tableModule.pages.page = item;
  props.tableModule.callback();
}

// 点击查询按钮时触发
function Search() {
  props.tableModule.callback();
}

// 点击重制触发
function Recover() {
  props.tableModule.queryForm = {};
  props.tableModule.callback();
}

//
function selectChange(porp) {
  if (props.tableModule.selectcallback) props.tableModule.selectcallback(porp);
}

function handleSelectionChange(val) {
  // console.log(`output->`, val);
  props.tableModule.multipleSelection = val;
}
</script>

<style scoped></style>
